package com.litbw.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JFrame;
import javax.swing.JTabbedPane;

import com.litbw.publicobservable.BasicUIMessage;
import com.litbw.publicobservable.LoginMessage;
import com.litbw.publicobservable.LogoutMessage;

public class MainGUI extends JFrame implements Observer {

	/**
	 * Generated serial version UID.
	 */
	private static final long serialVersionUID = -9087821759078350963L;

	/**
	 * Title to the screen.
	 */
	private static final String GUI_TITLE = "Leave It To Beweavers Interface";
	
	/**
	 * Default width of window.
	 */
	private static final int DEF_WND_WIDTH  = 800;
	
	/**
	 * Default height of window.
	 */
	private static final int DEF_WND_HEIGHT = 600;
	
	/**
	 * The tabs that will display profile, events, contests, etc.
	 */
	private JTabbedPane tabs;
	
	public static void main(final String... the_agrs) {
		
		/*
		User judge = null;
		try {
			judge = new User("joeshmoe@uw.edu");
			judge.changePassword("N7jcddcj$");
			judge.setAddress("123 nowhere");
			judge.setCity("sticks");
			judge.setFirst("That");
			judge.setLast("Guy");
		} catch (Exception ex) { ex.printStackTrace(); }
		DBUserAdapter.addNewUser(judge);
		
		User user = null;
		try {
			user = new User("morris4019@gmail.com");
			user.changePassword("N7jcddcj$");
			user.setAddress("38825 180 ave se");
			user.setCity("auburn");
			user.setFirst("Michael");
			user.setLast("Morris");
		} catch (Exception ex) { ex.printStackTrace(); }
		
		DBUserAdapter.addNewUser(user);
		*/
		/*
		Contest contest = new Contest();
		contest.setId(1);
		contest.setDescription("just a whole lot of weaving");
		contest.addRule("dont talk about this contest");
		contest.addRule("dont talk about this contest");
		contest.addRule("NEVER TALK ABOUT THIS CONTEST");
		contest.setEventParentId(1);
		contest.addJudge(judge);
		
		Entry entry = new Entry(user, new Draft(user));
		entry.setDescription("michaels entry");
		entry.setId(1);
		entry.setWaiverSigned(true);
		entry.setWinner(false);
		entry.addContestId(1);
		DBEntryAdapter.addEntry(entry);
		
		contest.addEntry(entry);
		DBContestAdapter.addContest(contest);
				
		Event event = new Event();
		event.addCategory(contest);
		event.setDate("2/24/2013");
		event.setDescription("Come on down for sum fun");
		event.setId(1);
		event.setLocation("The Tacoma Dome");
		event.setTime(200);
		
		DBEventAdapter.addEvent(event);
		*/
		/*
		User user = DBUserAdapter.getUser("joeshmoe@uw.edu");
		if (user == null)
			System.out.println("no user");
		else
			System.out.println("user");
		*/
		new MainGUI();
		
	}
	
	/**
	 * Create a new instance of the MainGUI.
	 */
	public MainGUI() {
		
		super(GUI_TITLE);

		addComponents();

		setupWindow();
		
		setVisible(true);
		
	}
	
	/**
	 * Setup the window.
	 */
	private void setupWindow() {
		
		// Setup all the window ish here.
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
				
		pack();
		
		// Setup the size of the window.
		setPreferredSize(new Dimension((int)getSize().getWidth(), 500));
		setMinimumSize(new Dimension((int)getSize().getWidth(), 500));
		
		setSize(DEF_WND_WIDTH, DEF_WND_HEIGHT);
		
	}
	
	/**
	 * Method to add the components of the main GUI.
	 * @author Michael Morris
	 * @edited Silvia Chita
	 */
	private void addComponents() {
		
		// Create the main tabbed pane.
		tabs = new JTabbedPane();
		add(tabs, BorderLayout.CENTER);

		// Create all panels first to aid in observer setting.
		final LoginPanel login_panel = new LoginPanel();
		final EventPanel event_panel = new EventPanel();
		final RegisterPanel register_panel = new RegisterPanel();
		final RegisterEventPanel register_event_panel = new RegisterEventPanel();
		final EventDetailPanel event_detail_panel = new EventDetailPanel();
		final UserProfilePanel user_profile_panel = new UserProfilePanel();
		
		// Add the login panel to the north region.
		login_panel.addObserver(this);
		login_panel.addObserver(user_profile_panel);
		login_panel.addObserver(event_detail_panel);
		login_panel.addObserver(register_event_panel);
		add(login_panel, BorderLayout.NORTH);
		
		// Create tabs -- all the tabs will go in this section, and then
		// any classes which need to send messages to each other can also 
		// add observers.
		// --------------------------------------------------------------

		// Setup the Event tab.
		event_panel.addObserver(this);
		event_panel.addObserver(event_detail_panel);
		tabs.add(event_panel);
		
		// Setup the Event Detail tab.
		event_detail_panel.addObserver(this);
		tabs.add(event_detail_panel);
		tabs.setEnabledAt(1, false);
		
		// Setup the Registration tab.
		register_event_panel.addObserver(this);
		register_event_panel.addObserver(user_profile_panel);
		tabs.add(register_event_panel);
		tabs.setEnabledAt(2, false);
		
		// Setup the User Profile Tab
		user_profile_panel.addObserver(this);
		user_profile_panel.addObserver(login_panel);
		tabs.add(user_profile_panel);
		//set to enabled only for testing!!!!!
		tabs.setEnabledAt(3, false);
		
		// Setup the New User tab.
		register_panel.addObserver(this);
		register_panel.addObserver(login_panel);
		register_panel.addObserver(event_detail_panel);
		register_panel.addObserver(user_profile_panel);
		tabs.add(register_panel);
		tabs.setEnabledAt(4, true);
		
		// --------------------------------------------------------------

	}
	
	@Override
	public void dispose() {
		// Do any needed cleanup of resources here... called on close.
		super.dispose();
	}

	/**
	 * @author Michael Morris
	 * @edited Silvia Chita
	 * @edited Trygve Stageberg
	 */
	@Override
	public void update(Observable obs, Object arg) {

		if (arg instanceof LogoutMessage) {
			tabs.setEnabledAt(getTabWithPanelType(RegisterEventPanel.class), false);
		
			// Disable the user profile tab
			tabs.setEnabledAt(getTabWithPanelType(UserProfilePanel.class), false);
		
			// Enable the new user panel
			tabs.setEnabledAt(getTabWithPanelType(RegisterPanel.class), true);
			
			// Show the events panel
			//show the events page
			final int eventpos = getTabWithPanelType(EventPanel.class);

			//switch to the events tab
			if (eventpos >= 0) {
				tabs.setSelectedIndex(eventpos);
				tabs.setEnabledAt(eventpos, true);
			}
			
		} else if (arg instanceof LoginMessage) {
			
			// Disable new user panel
			tabs.setEnabledAt(getTabWithPanelType(RegisterPanel.class), false);
			
			// Enable user profile panel
			tabs.setEnabledAt(getTabWithPanelType(UserProfilePanel.class), true);
				
		// Handle messages.
		} else if (arg instanceof BasicUIMessage) {
			
			BasicUIMessage.UISignal signal = ((BasicUIMessage)arg).getSignal();
			
			// TODO: Remove after debug.
			System.out.println("UI Recieved Signal: " + signal.toString());
			
			switch (signal) {
				case SHOW_EVENTS:
					//show the events page
					final int eventpos = getTabWithPanelType(EventPanel.class);

					//switch to the events tab
					if (eventpos >= 0) {
						tabs.setSelectedIndex(eventpos);
						tabs.setEnabledAt(eventpos, true);
					}
					break;
				case SHOW_REGISTER:
					// Show the register panel.
					final int regpos = getTabWithPanelType(RegisterPanel.class);
					
					//Switch to the registration tab
					if (regpos >= 0) {
						tabs.setSelectedIndex(regpos);
						tabs.setEnabledAt(regpos, true);
					}
					
					break;
				
				case SHOW_USER_PROFILE:
					final int profpos = getTabWithPanelType(UserProfilePanel.class);
					if (profpos >= 0) {
						tabs.setSelectedIndex(profpos);
						tabs.setEnabledAt(profpos, true);
					}
					
					break;
			
				case SHOW_REGISTER_EVENT:
					// Show the register event panel.
					final int regepos = getTabWithPanelType(RegisterEventPanel.class);
					
					//Switch to the registration event tab
					if (regepos >= 0) {
						tabs.setSelectedIndex(regepos);
						tabs.setEnabledAt(regepos, true);
					}
						
					break;
				case SHOW_EVENT_DETAIL:
					// find the tab index.
					final int pos = getTabWithPanelType(EventDetailPanel.class);
					
					// Switch to the tab if we can find it.
					if (pos >= 0) {
						tabs.setSelectedIndex(pos);
						tabs.setEnabledAt(pos, true);
					}
					break;
			}
			
		} 
		
	}
	
	/**
	 * Retrieve the tab index based on the Class of component added as its
	 * contents.
	 * @param c The Class c of the contents which are in the tab you want.
	 * @return The index of the tab or -1 if not found.
	 */
	@SuppressWarnings("rawtypes")
	private int getTabWithPanelType(final Class c) {
		
		int index = -1;
		
		if (c != null) {
			
			for (int i = 0; i < tabs.getTabCount() && index < 0; i++) {
				if (tabs.getComponentAt(i).getClass().isAssignableFrom(c))
					index = i;
			
			}
		}
		
		return index;
		
	}
	
}
